package ar.edu.utn.frba.tadp.tp.grupo4.fotomultas.vehiculos;

import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import org.uqbar.commons.model.Entity;
import org.uqbar.commons.utils.ApplicationContext;

import ar.edu.utn.frba.tadp.tp.grupo4.fotomultas.capturas.Captura;
import ar.edu.utn.frba.tadp.tp.grupo4.fotomultas.categorias.Categoria;
import ar.edu.utn.frba.tadp.tp.grupo4.fotomultas.externos.VerificadorDePagos;
import ar.edu.utn.frba.tadp.tp.grupo4.fotomultas.homes.AdministradorCategorias;

@SuppressWarnings("serial")
public class Vehiculo extends Entity{
	
	public static final String NOMBRE = "nombre";
	public static int maxPuntosRegistro = 100;
	private String patente;
	private int puntosRegistro;
	private List<Captura> capturas = new ArrayList<Captura>();
	private List<Captura> capturasInvalidadas = new ArrayList<Captura>();
	private Set<Categoria> categorias = new HashSet<Categoria>();
	
	
	public Vehiculo(String patente) {
		this.patente = patente;
		this.setPuntosRegistro(maxPuntosRegistro);
	}
	
	public Captura addCaptura(Captura captura) {
		validarPerdonCaptura(captura);
		this.capturas.add(captura);
		this.restarPuntos(captura);
		
		AdministradorCategorias admin = ApplicationContext.getInstance().getSingleton(AdministradorCategorias.class);
		admin.validarCategorias(this);
		
		return captura;
	}

	private void validarPerdonCaptura(Captura unaCaptura) {
		
		if (capturas.size() > 0){
		
			Captura ultimaCaptura = getUltimaCaptura();
			
			if (ultimaCaptura.tieneMasDe1Anio()){
				unaCaptura.setPerdonada(true);
			}
		}
	}

	public void removeCaptura(Captura unaCaptura) {
		this.capturas.remove(unaCaptura);
		this.capturasInvalidadas.add(unaCaptura);
		sumarPuntos(unaCaptura);
		AdministradorCategorias admin = ApplicationContext.getInstance().getSingleton(AdministradorCategorias.class);
		admin.validarCategorias(this);
	}
	
	public void verificarPuntosRegistro(){
		if (getUltimaCaptura().tieneMasDe6Meses() && getMontoMultas() == 0){
			renovarPuntos();
		}
	}


	private void restarPuntos(Captura unaCaptura) {
		this.setPuntosRegistro(this.getPuntosRegistro() - unaCaptura.getPuntosInfraccion());
		
	}

	private void sumarPuntos(Captura unaCaptura) {
		this.setPuntosRegistro(this.getPuntosRegistro() + unaCaptura.getInfraccion().getPuntos());
	}

	public int getPuntosRegistro() {
		return this.puntosRegistro;
	}

	public double getMontoMultas() {
		double sumatoria = 0;
		for (Captura captura: capturas){
			sumatoria += captura.getMontoInfraccion();
		}
		return sumatoria;
	}

	public boolean estaEnLaCategoria(Categoria categoria) {
		return categorias .contains(categoria);
	}

	public void addCategoria(Categoria categoria) {
		
		if(!(categorias.contains(categoria))){
		categorias.add(categoria);
		categoria.notificar(this);
		}
	}

	public Set<Captura> getCapturasImpagas(){
		Set<Captura> caps = new HashSet<Captura>();
		for (Captura captura : capturas) {
			if (!captura.estaPagada()){
				caps.add(captura);
			}
		}
		return caps;
	}
	
	public void renovarPuntos(){
		setPuntosRegistro(maxPuntosRegistro);
	}
	
	public int cantidadDeInfracciones(){
		int i = 0;
		for (Captura captura : this.capturas) {
			if (!captura.estaPerdonada()){
				i++;
			}
		}
		return i;
	}
	
	public void verificarPagos() {
		VerificadorDePagos verificadorPagos = ApplicationContext.getInstance().getSingleton(VerificadorDePagos.class);
		for (Captura captura : getCapturasImpagas()) {
			if (verificadorPagos.estaPagada(getPatente(), 
											captura.getInfraccion().getTipo(),
											captura.getFecha(), captura.getZona().getZona())){
				captura.setPagada(true);
			}
		}
	}
	
	public List<Captura> getCapturas() {
		return capturas;
	}
	
	public void setCapturas(List<Captura> capturas) {
		this.capturas = capturas;
	}
	
	public List<Captura> getCapturasInvalidadas() {
		return capturasInvalidadas;
	}

	public Set<Categoria> getCategorias() {
		return categorias;
	}

	public String getPatente() {
		return patente;
	}
	
	public Captura getUltimaCaptura(){
		return capturas.get(capturas.size()-1);
	}

	public void verificarCategorias() {
		AdministradorCategorias admin = ApplicationContext.getInstance().getSingleton(AdministradorCategorias.class);
		admin.validarCategorias(this);
		
	}

	public void removeCategoria(Categoria categoria) {
		categorias.remove(categoria);
		
	}
	
	public void setPuntosRegistro(int puntosRegistro) {
		this.puntosRegistro = puntosRegistro;
	}

	public String getNombre(){
		return getPatente();
	}

}
